/*
 * servidorEntrada.cpp
 *
 *  Created on: Dec 13, 2013
 *      Author: m
 */

#include <iostream>
#include <stdlib.h>
#include <fstream>
#include <iostream>
#include <cstdlib>
#include <errno.h>
#include <sys/wait.h>
#include "../socket/inet.h"
#include "CPrinter.h"
#include "ArchivoIni.h"
#include "StringUtils.h"

#define CONFIG_FILE "config.ini"

extern int tcpoppas(int puerto);

using ipc::CPrinter;

int main ( int argc, char* argv[] )
{
    static char socketChar[15];         /* string que contiene el socket para el servidor de eco */

    std::string descartar;
    int puerto = 0;

    CPrinter::setHeader( "servidorEntrada" );

    // Leer el puerto del servicio de un archivo
    ArchivoIni configFile( CONFIG_FILE );

    puerto = StringUtils::StringToNumber<int>( configFile.getValue( "puertoEntrada" ) );

    if ( puerto == 0 )
    {
        CPrinter::printErr( "Error al leer el puerto del archivo de configuracion" );
        exit(1);
    }

    CPrinter::printOut( "Levantando server en puerto: %d", puerto );

    int                 socketPasivo;
    int                 socketConectado;          /* socket conectado al cliente */
    unsigned            clilen;                 /* longitud dir. cliente */
    struct sockaddr_in  cli_addr;

    if ( ( socketPasivo = tcpoppas( puerto ) ) < 0 )
    {
        CPrinter::printErr( "no se puede abrir el stream socket" );
        CPrinter::printErr( strerror( errno ) );
        exit(1);
    }

    CPrinter::printOut( "se hizo el open pasivo, socket: %d", socketPasivo );

    while( true )
    {
        clilen = sizeof( cli_addr );
        socketConectado = accept( socketPasivo, (struct sockaddr *) &cli_addr, &clilen );

        if ( socketConectado < 0 )
        {
            CPrinter::printErr( "error en el accept: %s", strerror( errno ) );
            exit( 1 );
        }
        sprintf(socketChar, "%d\n", socketConectado); /* Pasarle el socket al hijo que atiende */

        pid_t pid = fork();
        if ( pid == 0 )
        {
            if ( fork() == 0 )
            {
                close( socketPasivo );
                execlp( "./receptor", "receptor", socketChar, (char *) 0 );
                CPrinter::printErr( "Execlp ./receptor error: %s", strerror( errno ) );
            }
            else
            {
                close( socketPasivo );
                exit( 0 );
            }
        }
        else
        {
            int status;
            waitpid( pid, &status, WUNTRACED | WCONTINUED );
        }
    }

    return 0;
}
